package com.cgy.utils.base.fusing;

import com.cgy.utils.base.fusing.handler.FusingHandler;
import com.cgy.utils.base.fusing.setting.FusingCommandSetting;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Future;

/**
 * 
 * @author CH
 *
 */
public class Fusings<T> {
	/**
	 * 新建熔断
	 * @param fusingHandler
	 * @return
	 */
	public static <T>Fusing<T> newFusing(final FusingHandler<T> fusingHandler) {
		Fusing<T> fusing = new Fusing<T>(fusingHandler);
		return fusing;
	}
	/**
	 * 新建熔断
	 * @param fusingHandler
	 * @return
	 */
	public static <T>Fusing<T> newFusing(final FusingHandler<T> fusingHandler, final FusingCommandSetting fusingCommandSetting) {
		Fusing<T> fusing = new Fusing<T>(fusingHandler, fusingCommandSetting);
		return fusing;
	}
	/**
	 * 新建熔断
	 * @param handlers
	 * @return
	 */
	public static <T>List<T> newFusings(@SuppressWarnings("unchecked") final FusingHandler<T>... handlers) {
		List<T> lists = new ArrayList<T>();
		HystrixRequestContext initializeContext = HystrixRequestContext.initializeContext();
		try {
			for (FusingHandler<T> iFusingHandler2 : handlers) {
				lists.add(Fusings.execute(iFusingHandler2));
			}
		} finally {
			initializeContext.shutdown();
		}
		return lists;
	}
	
	/**
	 * 新建熔断
	 * @param handlers
	 * @return
	 */
	public static <T>List<Future<T>> newFusingsAsync(@SuppressWarnings("unchecked") final FusingHandler<T>... handlers) {
		if(null == handlers) {
			return null;
		}
		List<Future<T>> lists = new ArrayList<Future<T>>();
		HystrixRequestContext initializeContext = HystrixRequestContext.initializeContext();
		try {
			for (FusingHandler<T> iFusingHandler2 : handlers) {
				lists.add(Fusings.async(iFusingHandler2));
			}
		} finally {
			initializeContext.shutdown();
		}
		return lists;
	}
	/**
	 * 获取熔断结果
	 * @param iFusingHandler
	 * @return
	 */
	public static <T>T execute(final FusingHandler<T> iFusingHandler, final FusingCommandSetting fusingCommandSetting) {
		Fusing<T> newFusing = newFusing(iFusingHandler, fusingCommandSetting);
		return newFusing.execute();
	}

	/**
	 * 获取熔断结果
	 * @param iFusingHandler
	 * @return
	 */
	public static <T>T execute(final FusingHandler<T> iFusingHandler) {
		Fusing<T> newFusing = newFusing(iFusingHandler);
		return newFusing.execute();
	}
	
	/**
	 * 获取熔断结果
	 * @param iFusingHandler
	 * @return
	 */
	public static <T>Future<T> async(final FusingHandler<T> iFusingHandler) {
		Fusing<T> newFusing = newFusing(iFusingHandler);
		return newFusing.queue();
	}

	/**
	 *
	 * @param iFusingHandler
	 * @param fusingCommandSetting
	 * @param <T>
	 * @return
	 */
	public static <T>Future<T> async(final FusingHandler<T> iFusingHandler, final FusingCommandSetting fusingCommandSetting) {
		Fusing<T> newFusing = newFusing(iFusingHandler, fusingCommandSetting);
		return newFusing.queue();
	}
}
